package org.dialMsg.Producer;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.google.common.util.concurrent.RateLimiter;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.dialMsg.Pojo.BatchPostParam;
import org.dialMsg.Pojo.TDialResult;
import org.dialMsg.Server.ServerImp.*;
import org.dialMsg.Server.ServerInt.RobotExecLogService;
import org.dialMsg.Topic.RocketmqConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PreDestroy;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * @author DPF
 */
@Service
public class SendTopicBatch {
    private static final Logger logger = LoggerFactory.getLogger(SendTopicBatch.class);
    private final RedisTemplate<String, String> redisTemplate;
    private final ExecutorService executorService = Executors.newFixedThreadPool(15);
    private static final String value = RocketmqConstant.MyTopic().get(RocketmqConstant.TopicEnum.ROBOT_DIAL_RESULT_MSG_TOPIC);
    private final RocketMQTemplate rocketMQTemplate;
    @Autowired
    private TDialResultImp tDialResultImp;
    @Autowired
    private PostExampleHutoolBatch client;
    private static final RateLimiter rateLimiter = RateLimiter.create(100); // 每秒放行10个请求
    @Autowired
    private FactMessageSendApiServerImp factMessageSendApiServerImp;
    @Autowired
    private RobotExecLogService robotExecLogService;
   private static final String phone = "111222333444";

    // 定义SimpleDateFormat对象
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//    private static JSONObject dialData = new JSONObject();

    public SendTopicBatch(RocketMQTemplate rocketMQTemplate, RedisTemplate<String, String> redisTemplate) {
        this.rocketMQTemplate = rocketMQTemplate;
        this.redisTemplate = redisTemplate;
    }


    public String sendMessageBatch() throws InterruptedException {
        Long lastMaxId = Long.parseLong(redisTemplate.opsForValue().get("manage:creatAiData:lastMaxId"));


        List<TDialResult> tDialResults = tDialResultImp.queryIdByPhoneAfter(lastMaxId, phone);
        if (tDialResults.isEmpty()) {
            return "没有更多数据";
        }

        Long currentMaxId = lastMaxId;

        // 准备批量消息
        List<Message<String>> messageList = new ArrayList<>();
        List<String> allKeys = new ArrayList<>();
        List<BatchPostParam> postParams = new ArrayList<>();

        for (TDialResult tDialResult : tDialResults) {
            // 构造消息体
            JSONObject dialData = new JSONObject(); // 每次循环创建新的对象，避免数据污染
            dialData.put("dialId", tDialResult.getId());
            dialData.put("callType", tDialResult.getCallType());
            dialData.put("batchId", tDialResult.getDataSourceBatchId());
            dialData.put("phone", tDialResult.getPhone());
            dialData.put("sceneId", tDialResult.getBusinessId());
            dialData.put("caller", tDialResult.getOutboundNumber());
            dialData.put("roundCount", tDialResult.getRoundCount());
            dialData.put("robotId", tDialResult.getRobotId());
            dialData.put("transferResult", tDialResult.getBridgeResult());
            dialData.put("durationOfSeatConversing", tDialResult.getDurationOfSeatConversing());
            dialData.put("taskName", tDialResult.getShowName());
            dialData.put("batchName", tDialResult.getShowName());
            dialData.put("dataSourceType", tDialResult.getCallType());
            dialData.put("bankManager", tDialResult.getBankManager());
            dialData.put("bankOrgName", tDialResult.getBusinessName());
            dialData.put("batchDetailId", tDialResult.getDataSourceBatchDetailId());
            dialData.put("bankOrg", tDialResult.getBankOrg());
            dialData.put("followUserId", tDialResult.getFollowUser());

            JSONArray dataArray = new JSONArray();
            dataArray.add(dialData);
            JSONObject mainObject = new JSONObject();
            mainObject.put("accountId", tDialResult.getAccountId());
            mainObject.put("data", dataArray);
            String dialTaskMQMsg = JSON.toJSONString(mainObject);

            // 生成KEYS
            String KEYS = String.format("%s%s",
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),
                    RandomStringUtils.randomAlphabetic(18).toUpperCase()
            );
            allKeys.add(KEYS);

            executorService.submit(() -> {
                rateLimiter.acquire();
                // 生成话单中的语音文字
                try {
                    String content = "[{\"callContent\":\"喂（空1.2秒）您好，这里是珠海建行，您在我行有笔定期存款已经到期还未办理转存，我安排网点客户经理给您介绍下最新转存产品信息好吗？!(R130)\",\"callTime\":1739614767097,\"createTime\":\"2025-02-15 18:19:27\",\"flowNodeSeq\":\"R130\",\"hangup\":false,\"main\":false,\"matchCostTime\":0,\"needStudy\":false,\"nodeId\":\"df831ec0-48dc-11ec-8ea2-2766b20a6b2d\",\"playbackUid\":\"bc68f93446cbd7d428ab52a4edec71bc\",\"robot\":true,\"skipStat\":false,\"tips\":\"开场白\",\"voiceCostTime\":0},{\"analyseType\":6,\"asrResult\":\"你说什么？我没听清。\",\"callContent\":\"你说什么？我没听清。(Q61)\",\"callContentCutPos\":\"你/r,说/v,什么/r,？/w,我/r,没/v,听/v,清/LOC,。/w\",\"callTime\":1739614785964,\"createTime\":\"2025-02-15 18:19:45\",\"flowNodeSeq\":\"Q61\",\"hangup\":false,\"main\":false,\"matchCostTime\":0,\"needStudy\":false,\"qaEntity\":{\"highIntentionQa\":0,\"intentionTag\":\"What\",\"intentionType\":3,\"qaName\":\"227.tmpc_什么事\",\"qaUid\":61,\"qawords\":[{\"scroe\":0.5,\"word\":\"227.tmpc_什么事\"}],\"tagName\":\"227.tmpc_什么事\",\"targetWord\":\"你说#什么#\",\"type\":1},\"robot\":false,\"skipStat\":false,\"tips\":\"中性QA命中\",\"voiceCostTime\":0},{\"callContent\":\"是这样，来电是提醒您在我行有笔定期存款已经到期还未转存，建议您尽快办理转存，以免影响到您的收益。稍后我让客户经理给您具体介绍下转存产品信息及流程好吗？(R104)\",\"callTime\":1739614785964,\"createTime\":\"2025-02-15 18:19:45\",\"flowNodeSeq\":\"R104\",\"hangup\":false,\"main\":false,\"matchCostTime\":0,\"needStudy\":false,\"playbackUid\":\"4997788b06bf0641fdd1d3a729e65e06\",\"robot\":true,\"skipStat\":false,\"voiceCostTime\":0},{\"analyseType\":7,\"asrResult\":\"你再说一遍，我没听清。\",\"callContent\":\"你再说一遍，我没听清。(Y4)\",\"callContentCutPos\":\"你/r,再说/d,一遍/m,，/w,我/r,没/v,听/v,清/LOC,。/w\",\"callTime\":1739614803510,\"createTime\":\"2025-02-15 18:20:03\",\"flowNodeSeq\":\"Y4\",\"hangup\":false,\"main\":false,\"matchCostTime\":0,\"needStudy\":false,\"robot\":false,\"skipStat\":false,\"tips\":\"语态识别命中\",\"toneEntity\":{\"attribute\":6,\"attributeCategoryName\":\"sys.重复\",\"attributeCategoryUid\":4,\"targetWord\":\"Model\",\"tonewords\":[{\"scroe\":0.9999995231628418,\"value\":6,\"word\":\"sys.重复\"}]},\"voiceCostTime\":0},{\"callContent\":\"是这样，来电是提醒您在我行有笔定期存款已经到期还未转存，建议您尽快办理转存，以免影响到您的收益。稍后我让客户经理给您具体介绍下转存产品信息及流程好吗？(R104)\",\"callTime\":1739614803510,\"createTime\":\"2025-02-15 18:20:03\",\"flowNodeSeq\":\"R104\",\"hangup\":false,\"main\":false,\"matchCostTime\":0,\"needStudy\":false,\"playbackUid\":\"4997788b06bf0641fdd1d3a729e65e06\",\"robot\":true,\"skipStat\":false,\"voiceCostTime\":0},{\"analyseType\":1,\"callContent\":\"被叫挂断(UE)\",\"callTime\":1739614814465,\"createTime\":\"2025-02-15 18:20:14\",\"flowNodeSeq\":\"UE\",\"hangup\":false,\"main\":false,\"matchCostTime\":0,\"needStudy\":false,\"robot\":false,\"skipStat\":false,\"tips\":\"被叫挂断\",\"voiceCostTime\":0,\"voiceText\":\"被叫挂断\"}]";
                    robotExecLogService.addLog(tDialResult.getId(), content, tDialResult.getTimeCreate());
                } catch (Exception e) {
                    logger.error("生成话单中的语音文字时出错，忽略异常继续执行", e);
                }
            });
            // 构建消息并添加到批量列表
            messageList.add(MessageBuilder.withPayload(dialTaskMQMsg)
                    .setHeader("KEYS", KEYS)
                    .build());
            // 构造 POST 参数
            int randomStatus = getRandomStatus();
            postParams.add(buildPostParam(tDialResult, randomStatus, phone));
            // 更新最大ID
            if (tDialResult.getId() > currentMaxId) {
                currentMaxId = Long.valueOf(tDialResult.getId());
            }
        }
        // 存入Redis
        redisTemplate.opsForValue().set("manage:creatAiData:lastMaxId", currentMaxId.toString());

        executorService.submit(() -> {
            rateLimiter.acquire();
            // 批量发送MQ消息下发任务
            if (!messageList.isEmpty()) {
                try {
                    for (Message<String> message : messageList) {
                        rocketMQTemplate.send(value, message);
                    }
                } catch (Exception e) {
                    logger.error("批量发送RocketMQ消息失败", e);
                }
            }
        });

        executorService.submit(() -> {
            rateLimiter.acquire();
            //填写跟进记录
            try {
                sendBatchPostRequest(postParams);
            } catch (Exception e) {
                logger.error("postExample请求失败", e);
            }
        });

        executorService.submit(() -> {
            rateLimiter.acquire();
            // 同步报表引擎数据
            try {
                factMessageSendApiServerImp.sendFactMessage(tDialResults);
            } catch (Exception e) {
                logger.error("同步报表引擎数据时出错，忽略异常继续执行", e);
            }
        });

        // 将返回语句移到方法末尾
        return String.join(",", allKeys);
    }

    /**
     * 批量发送 POST 请求
     */
    private void sendBatchPostRequest(List<BatchPostParam> postParams) {
        try {
            client.postBatchExample(postParams);
            logger.info("批量 POST 请求成功，数据量: {}", postParams.size());
        } catch (Exception e) {
            logger.error("批量 POST 请求失败，数据量: {}，错误: {}", postParams.size(), e.getMessage(), e);
        }
    }

    /**
     * 生成随机状态
     */
    private int getRandomStatus() {
        int[] statusArray = {11, 20, 21};
        return statusArray[RandomUtils.nextInt(0, statusArray.length)];
    }

    /**
     * 构造 POST 参数
     */
    private BatchPostParam buildPostParam(TDialResult tDialResult, int randomStatus, String phone) {
        if (tDialResult.getCallType() == 1) {
            tDialResult.setDurationOfRinging(0);
            tDialResult.setDurationOfSeatConversing(0);
            tDialResult.setBridgeResult(0);
            tDialResult.setHumanStatus(10);
        }
        return new BatchPostParam(
                tDialResult.getBusinessId(),
                randomStatus,
                phone,
                tDialResult.getCallType(),
                tDialResult.getTimeCreate(),
                tDialResult.getBankManager(),
                tDialResult.getId(),
                tDialResult.getBridgeResult()
        );
    }
    @PreDestroy
    public void destroy() {
        if (executorService != null && !executorService.isShutdown()) {
            executorService.shutdown();
        }
    }
}